﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

using NUnit.Framework;

using ERPStore.Extensions;

using Microsoft.Practices.Unity;

namespace ERPStore.NewsLetters.Tests.Services
{
	[TestFixture]
	public class NewsLetterServiceTests : ERPStore.Tests.TestBase
	{
		public NewsLetterServiceTests()
		{

		}

		[SetUp]
		public override void Initialize()
		{
			base.Initialize();

			var container = ERPStore.GlobalConfiguration.Configuration.DependencyResolver.GetContainer();
			container.RegisterType<ERPStore.NewsLetters.Services.IEmailListSourceProvider, TestRecipientSourceProvider>("testrecipientsourceprovider", new ContainerControlledLifetimeManager());

			NewsLetterService = container.Resolve<ERPStore.NewsLetters.Services.NewsLettersService>();
		}

		protected ERPStore.NewsLetters.Services.NewsLettersService NewsLetterService { get; set; }

		#region SMTPServer

		public Models.SMTPSettings CreateValidSMTPServer()
		{
			var result = NewsLetterService.CreateSMTPServer();
			result.Name = Guid.NewGuid().ToString();

			return result;
		}

		public Models.SMTPSettings GetNewPersistedSMTPServer()
		{
			var result = CreateValidSMTPServer();
			NewsLetterService.SaveSMTPServer(result);
			return result;
		}

		[Test]
		public void CreateSMTPServer()
		{
			var result = CreateValidSMTPServer();

			Assert.IsNotNull(result);
		}

		[Test]
		public void Create_Empty_SMTPServer_And_Validate()
		{
			var result = NewsLetterService.CreateSMTPServer();
			var rules = NewsLetterService.ValidateSMTPServer(result);
			Assert.AreNotEqual(rules.Count,0);
		}

		[Test]
		public void SMTPServer_CRUD()
		{
			var result = NewsLetterService.CreateSMTPServer();
			result.Name = Guid.NewGuid().ToString();

			NewsLetterService.SaveSMTPServer(result);
			Assert.AreNotEqual(result.Id, 0);

			var id = result.Id;
			result = NewsLetterService.GetSMTPServerById(result.Id);

			result.HostName = "Test";
			// Update;
			NewsLetterService.SaveSMTPServer(result);
			Assert.AreEqual(result.Id, id);

			result = NewsLetterService.GetSMTPServerById(result.Id);
			Assert.AreEqual(result.HostName, "Test");

			NewsLetterService.DeleteSMTPServer(id);

			result = NewsLetterService.GetSMTPServerById(id);
			Assert.IsNull(result);
		}

		[Test]
		public void SMTPServer_List()
		{
			var result = NewsLetterService.CreateSMTPServer();
			result.Name = Guid.NewGuid().ToString();

			NewsLetterService.SaveSMTPServer(result);

			var list = NewsLetterService.GetSMTPServerList();

			Assert.Greater(list.Count, 0);

			NewsLetterService.DeleteSMTPServer(result.Id);
		}

		#endregion

		#region EmailListSource

		public Models.EmailListSource CreateValidEmailListSource()
		{
			var list = NewsLetterService.GetEmailListSourceTypeList();
			var source = NewsLetterService.CreateEmailListSource(list.First(i => i.Key == "69EFEC43-EFA8-409B-85DA-C107442F65EC").Key);
			source.Name = Guid.NewGuid().ToString();

			return source;
		}

		public Models.EmailListSource GetNewPersistedEmailListSource()
		{
			var result = CreateValidEmailListSource();
			NewsLetterService.SaveEmailListSource(result);
			return result;
		}

		[Test]
		public void Create_EmailListSource()
		{
			var source = CreateValidEmailListSource();

			Assert.IsNotNull(source);
		}

		[Test]
		public void Validate_Empty_EmailListSource()
		{
			var list = NewsLetterService.GetEmailListSourceTypeList();
			var source = NewsLetterService.CreateEmailListSource(list.First().Key);
			var br = NewsLetterService.ValidateEmailListSource(source);

			Assert.AreNotEqual(br.Count, 0);
		}

		[Test]
		public void Get_EmailListSourceType_List()
		{
			var list = NewsLetterService.GetEmailListSourceTypeList();

			Assert.AreNotEqual(list.Count, 0);
		}

		[Test]
		public void EmailListSource_CRUD()
		{
			var list = NewsLetterService.GetEmailListSourceTypeList();
			var source = NewsLetterService.CreateEmailListSource(list.First().Key);

			source.Name = Guid.NewGuid().ToString();

			// CREATE
			NewsLetterService.SaveEmailListSource(source);

			Assert.AreNotEqual(source.Id, 0);
			var id = source.Id;

			// GET
			source = NewsLetterService.GetEmailListSourceById(id);
			Assert.IsNotNull(source);

			var newName = Guid.NewGuid().ToString();
			source.Name = newName;
			// UPDATE
			NewsLetterService.SaveEmailListSource(source);

			// GET
			source = NewsLetterService.GetEmailListSourceById(id);
			Assert.AreEqual(source.Name, newName);

			// DELETE
			NewsLetterService.DeleteEmailListSource(id);

			// GET
			source = NewsLetterService.GetEmailListSourceById(id);
			Assert.IsNull(source);
		}

		#endregion

		#region NewsLetter

		public Models.NewsLetter CreateValidNewsLetter()
		{
			var newsLetter = NewsLetterService.CreateNewsLetter();
			newsLetter.Content = Guid.NewGuid().ToString();
			newsLetter.FileName = Guid.NewGuid().ToString();

			return newsLetter;
		}

		public Models.NewsLetter GetNewPersistedNewsLetter()
		{
			var newsLetter = CreateValidNewsLetter();
			NewsLetterService.SaveNewsLetter(newsLetter);
			return newsLetter;
		}

		[Test]
		public void Create_NewsLetter()
		{
			var newsLetter = CreateValidNewsLetter();
			Assert.IsNotNull(newsLetter);
		}

		[Test]
		public void Create_Empty_NewsLetter_And_Validate()
		{
			var newsLetter = NewsLetterService.CreateNewsLetter();
			var br = NewsLetterService.ValidateNewsLetter(newsLetter);

			Assert.AreNotEqual(br.Count, 0);
			Assert.IsNotNull(newsLetter.ContentViewName);
		}

		[Test]
		public void NewsLetter_CRUD()
		{
			var newsLetter = NewsLetterService.CreateNewsLetter();
			newsLetter.FileName = "_test";
			newsLetter.Content = Guid.NewGuid().ToString();
			newsLetter.OwnerId = 1;

			NewsLetterService.SaveNewsLetter(newsLetter);
			var id = newsLetter.Id;
			var content = newsLetter.Content;

			Assert.AreNotEqual(id, 0);

			newsLetter = NewsLetterService.GetNewsLetterById(id);

			Assert.AreEqual(content, newsLetter.Content);

			NewsLetterService.DeleteNewsLetter(id);

			int count = 0;
			var filter = new Models.NewsLetterListFilter();
			var list = NewsLetterService.GetNewsLettersList(filter, out count);
			Assert.AreNotEqual(list.Any(i => i.Id == id), true);
		}

		#endregion

		#region Campaign

		[Test]
		public void Create_Campaign()
		{
			var campaign = NewsLetterService.CreateCampaign();

			Assert.IsNotNull(campaign);
		}

		[Test]
		public void Create_Empty_Campaign_And_Validate()
		{
			var campaign = NewsLetterService.CreateCampaign();
			var rl = NewsLetterService.ValidateCampaign(campaign);

			Assert.AreNotEqual(rl.Count, 0);
		}

		public Models.Campaign GetValidCampaign()
		{
			// PREREQUIS
			var smtpServer = GetNewPersistedSMTPServer();
			var source = GetNewPersistedEmailListSource();
			var newsLetter = GetNewPersistedNewsLetter();

			var campaign = NewsLetterService.CreateCampaign();
			campaign.Description = Guid.NewGuid().ToString();
			campaign.EmailListSourceId = source.Id;
			campaign.Name = Guid.NewGuid().ToString();
			campaign.NewsLetterId = newsLetter.Id;
			campaign.PublicKey = Guid.NewGuid().ToString();
			campaign.ReplyToEmail = "test@test.com";
			campaign.ReplyToEmailName = "test";
			campaign.SMTPServerId = smtpServer.Id;
			campaign.State = Models.SendState.Pending;

			return campaign;
		}


		[Test]
		public void Campaign_CRUD()
		{
			var campaign = GetValidCampaign();

			// INSERT
			NewsLetterService.SaveCampaign(campaign);
			Assert.AreNotEqual(campaign.Id, 0);

			var id = campaign.Id;

			// GET
			campaign = NewsLetterService.GetCampaignById(id);
			campaign.Name = Guid.NewGuid().ToString();

			var name = campaign.Name;

			// UPDATE
			NewsLetterService.SaveCampaign(campaign);
			campaign = NewsLetterService.GetCampaignById(id);
			Assert.AreEqual(campaign.Name, name);

			// DELETE
			NewsLetterService.DeleteCampaign(campaign.Id);

			var filter = new Models.CampaignListFilter();
			int count = 0;
			var list = NewsLetterService.GetCampaignList(filter, out count);

			Assert.AreEqual(list.Any(i => i.Id == id), false);
		}

		[Test]
		public void Schedule_Campaign()
		{
			var campaign = GetValidCampaign();
			NewsLetterService.SaveCampaign(campaign);

			var settings = GlobalConfiguration.Configuration.DependencyResolver.GetService<Models.Settings>();
			var parameters = new Dictionary<string, object>();
			parameters.Add("StartDate", DateTime.Now);
			parameters.Add("Campaign", campaign);
			parameters.Add("Settings", settings);

			var activity = new Workflows.ScheduleCampaign();

			CloudSoft.Workflows.ManualWorkflowWorkItem.Run(
				activity
				, parameters
			);

			var pendingList = NewsLetterService.GetPendingItemList(100);
			Assert.AreEqual(pendingList.Any(i => i.CampaignId == campaign.Id), true);

			NewsLetterService.CancelScheduledCampaign(campaign.Id);
		}

		#endregion

		#region recipient

		[Test]
		public void Recipient_CRUD()
		{
			var recipient = NewsLetterService.CreateEmailRecipient();
			recipient.Email = string.Format("{0}@email.com", Guid.NewGuid().ToString());

			// INSERT
			NewsLetterService.SaveEmailRecipient(recipient);
			Assert.AreNotEqual(recipient.Id, 0);

			var id = recipient.Id;
			var email = recipient.Email;

			// GET
			recipient = NewsLetterService.GetEmailRecipientById(id);
			recipient.FullName = Guid.NewGuid().ToString();
			var name = recipient.FullName;

			// UPDATE
			NewsLetterService.SaveEmailRecipient(recipient);

			recipient = NewsLetterService.GetEmailRecipientByEmail(email);
			Assert.AreEqual(recipient.FullName, name);
		}

		#endregion
	}
}
